/*
* Copyright 2004-2010 mb_sx@hotmail.com
* All Rights Reserved.
*/
using System;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Threading;
using System.Globalization;
using Outlook = Microsoft.Office.Interop.Outlook;
using DeskNotes.Utils;

namespace DeskNotes
{
	/// <summary>
	/// Note class holds the data from data set and is used by UI (Forms) to manipulate with data.
	/// It is also responsible for handling of data updates through its parent class into Dataset and
	/// XML file.
	/// 
	/// NOTE: All properties for DeskNotes attributes like colors, fonts, text, position,... are used as 
	/// triggers for save to disk. When such a property is set then Note performs update of dataset 
	/// which ends by XML file being saved to disk.
	/// </summary>
	public class Note : IPrintableNote	
	{
		private string text;
		private long id = 0;
		private Font font = null;
		private Color textColor;
		private Color backgroundColor;
        private double opacity = 1.0;
        private string outlookEntryID = null;
        private DateTime lastModificationTime = DateTime.MinValue;
        private DateTime syncTime = DateTime.MinValue;
        private bool onTop = false;
        private bool hidden = false;
        private bool switchable = false;
        private bool showFormatting = false;
        private Rectangle position;
        private DateTime alarm = new DateTime(0);
        public static Rectangle DefaultPosition = new Rectangle(100, 100, 300, 300);
        //private DeskNote dataHandler;
        private DeskNotesData dataHandler;
        private NoteForm myForm = null;
        private RemindersActionHandler missedRemindersHandler = null;

        public DateTime SyncTime
        {
            get { return syncTime; }
            set { 
                syncTime = value;
                if (this.id != 0)
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.SyncTime = this.syncTime;
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }
            }
        }

        public DateTime LastModificationTime
        {
            get { return lastModificationTime; }
            set { 
                lastModificationTime = value;
                if (this.id != 0)
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.LastModificationTime = lastModificationTime;
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }

            }
        }

        public string OutlookEntryID
        {
            get { return outlookEntryID; }
            set { 
                outlookEntryID = value;
                if (this.id != 0)
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.OutlookEntryID = outlookEntryID;
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }
            }
        }

        public bool ShowFormatting
        {
            get { return showFormatting; }
            set
            {
                showFormatting = value;
                if (this.id == 0)
                {
                    UpdateDataSet();
                }
                else
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.ShowFormatting = showFormatting;
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }
            }
        }
        public double Opacity
        {
            get { return opacity; }
            set { 
                opacity = value;
                if (this.id == 0)
                {
                    UpdateDataSet();
                }
                else
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.opacity = opacity;
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }
            }
        }
		

		/// <summary>
		/// Used for drag & drop at archiving
		/// </summary>
		public Note()
		{
		}

        internal Note(long id)
        {
            this.id = id;
            this.position = DefaultPosition;
        }
		

		
		public Note(long id, string text, Rectangle pos, Color backColor, Color textColor, Font font, bool switchable)
		{
			this.id = id;
			this.text = text;
			this.position = pos;
			this.backgroundColor = backColor;
			this.textColor = textColor;
            this.switchable = switchable;
            if (null != font)
                this.font = font;
		}
        /// <summary>
        /// Constructor used when New desknote is created via menu as user action.
        /// </summary>
        /// <param name="id">note ID, should be 0 <i>zero</i></param>
        /// <param name="text">note's text</param>
        /// <param name="pos">rectangel occupied by note on a desktop</param>
        /// <param name="backColor">background color of a note. Usually default one.</param>
        /// <param name="textColor">text color of note's text. Usually default one.</param>
        public Note(long id, string text, Rectangle pos, Color backColor, Color textColor, bool switchable)
        {
            this.id = id;
            this.text = text;
            this.position = pos;
            this.backgroundColor = backColor;
            this.textColor = textColor;
            this.switchable = switchable;
        }
       
		/// <summary>
		/// Following properties when <b>set</b> trigger Save action for given desknote.
		/// Save action results in writing XML data file to disk.
		/// <b>NOTE:</b> Don't set these properties from inside Note class, like during 
		/// initialization, to avoid unnecessary file saves.
		/// </summary>
		public Color BackgroundColor
		{
			get 
			{
				return backgroundColor;
			}
			set 
			{
				backgroundColor = value;
                if (this.id == 0)
                {
                    UpdateDataSet();
                }
                else
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.backColor = backgroundColor.ToArgb();
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }
			}
		}

		public Color TextColor
		{
			get 
			{
				return textColor;
			}
			set 
			{
				textColor = value;
                if (this.id == 0)
                {
                    UpdateDataSet();
                } 
                else
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.textColor = textColor.ToArgb();
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }
			}
		}

		public Rectangle Position
		{
			get 
			{
				return position;

			}
			set 
			{
				position = value;
                if (this.id == 0)
                    UpdateDataSet();
                else
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        DeskNoteDB.positionRow[] positionRow = row.GetpositionRows();
                        if (positionRow.Length != 0)
                        {
                            positionRow[0].x = value.X;
                            positionRow[0].y = value.Y;
                            positionRow[0].height = value.Height;
                            positionRow[0].width = value.Width;
                            dataHandler.position.AcceptChanges();
                            //dataHandler._DeskNote.AcceptChanges();
                            //dataHandler.Save();
                        }
                    }
                }
			}
		}

        /// <summary>
        /// ExtraFont is used only for backward compatibility with older data files.
        /// It is read and used for DeskNote creation, but never saved again as it is saved inside RTF.
        /// </summary>
		public Font ExtraFont
		{
			get 
			{
				return font;
			}
			
		}

		/// <summary>
		/// Property sets alarm time and it also sets and starts timer
		/// 
		/// </summary>
		public DateTime Alarm
		{
			get 
			{
				return alarm;
			}
			set 
			{
				alarm = value;
                if (this.id == 0)
                {
                    UpdateDataSet();
                }
                else
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.alarm = alarm;
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }
			}
		}

		/// <summary>
		/// Property returns reminder/alarm text formatted according to locale set.
		/// </summary>
		public string AlarmText
		{
			get 
			{
				DateTimeFormatInfo myDTFI = System.Windows.Forms.Application.CurrentCulture.DateTimeFormat;
				return myDTFI.GetAbbreviatedDayName(alarm.DayOfWeek) + " " 
					+ alarm.ToString(myDTFI.ShortDatePattern) + " " + alarm.ToString(myDTFI.ShortTimePattern);
			}
		}

        /// <summary>
        /// Text of DeskNote in RTF since version 2.0
        /// Can be in plain text for data from previous version.
        /// </summary>
		internal string Text
		{
			get 
			{ return text;}
			set 
			{ 
                text = value;
                if (this.id == 0)
                    UpdateDataSet();
                else
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.text = this.text;
                        row.LastModificationTime = this.lastModificationTime;
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }
			}
		}
        /// <summary>
        /// Returns plain text representation  of desknote
        /// </summary>
        internal string PlainText
        {
            get
            {
                return RtfConverter.Text(this.text);
            }
        }
        /// <summary>
        /// Returns 10 chars at maximum of plain text for DeskNote.
        /// </summary>
        internal string ShortPlainText
        {
            get
            {
                string plain = RtfConverter.Text(this.text);
                return plain.Length > 14 ? plain.Substring(0, 13) : plain;
            }
        }

        /// <summary>
        /// If True the DeskNote is the top most window on desktop. 
        /// Covers any other active application window.
        /// </summary>
		public bool OnTop
		{
            get
            { return onTop; }
			set 
			{	
                onTop = value;
                if (this.id == 0)
                {
                    UpdateDataSet();
                }
                else
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.onTop = onTop;
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }
			}
		}
        /// <summary>
        /// Changes Desknote style to be switchable by Windows Alt+Tab and visible in taskbar.
        /// Creates completely new NoteForm and assigns it to this DeskNote. All visible elements
        /// are set to same state as before the change.
        /// </summary>
        public bool Switchable
        {
            get { return switchable; }
            set {
                Logger.WriteLine("'{0}' Switchable called set to {1}", this.ShortPlainText, value);
                switchable = value;

                NoteForm old = this.myForm;
                int caretPosition = old.txtNote.SelectionStart;
                bool formattingBar = old.toolStripRTF.Visible;
                old.UpdateText();

                NoteForm nf = new NoteForm(switchable);
                nf.Bounds = Position; 
                nf.NoteData = this;
                this.MyForm = nf;
               
                // Old form should not be deactivated while new is created
                old.Deactivate -= old.NoteForm_Deactivate;
                // Show new form
                nf.Show();
                // Show or hide formatting toolbar inside shown desknote form
                nf.SetEditingToolbar(formattingBar);

                // Unregister Closing event so form is not hidden instead.
                old.FormClosing -= old.NoteForm_FormClosing;
                old.Close();
                // Set new form to handle activated events
                nf.Activated += nf.NoteForm_Activated;
                // Top most note is reset when note is added. It needs to
                // be set again after creation.
                this.dataHandler.ConfirmTopMost();
                
                myForm.Activate();
                myForm.txtNote.Select();
                myForm.txtNote.SelectionStart = caretPosition;
                myForm.SetResizableBorder();

                if (this.id == 0)
                {
                    UpdateDataSet();
                }
                else
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.switchable = this.switchable;
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }
            }
        }

        /// <summary>
        /// If True then DeskNote is invisible on desktop.
        /// </summary>
		public bool Hidden 
		{
			get 
			{
				return hidden;
			}

			set 
			{
				hidden = value;
				if (hidden)
				{
					myForm.Hide();
				}
                if (this.id == 0)
                    UpdateDataSet();
                else
                {
                    DeskNoteDB.DeskNoteRow row = GetMyDataSetRow();
                    if (null != row)
                    {
                        row.hidden = this.hidden;
                        //dataHandler._DeskNote.AcceptChanges();
                        //dataHandler.Save();
                    }
                }
			}
		}

		public void ResetAlarm()
		{
			alarm = DateTime.MinValue;
					
			//Save();
		}
		
		/// <summary>
		/// Following properties are not saved when changed.
		/// </summary>
		public long ID
		{
			get 
			{
				return id;
			}
		}

		public bool HasAlarm
		{
			get
			{
				if (alarm.Equals(DateTime.MinValue))
					return false;
				else
					return true;
			}
		}

		public NoteForm MyForm
		{
			get 
			{
				return myForm;
			}
			set 
			{
				myForm = value;
			}
		}

		internal RemindersActionHandler MissedRemindersHandler
		{
			get 
			{
				if (null == missedRemindersHandler)
					missedRemindersHandler = new RemindersActionHandler(myForm.HandleRemindersAction);
				return missedRemindersHandler;
			}
		}

		internal DeskNotesData DataHandler
		{
			set 
			{
				dataHandler = value;
			}
			get 
			{
				return dataHandler;
			}
		}

		/*public DeskNote DataSet
		{
			set 
			{
				dataHandler = value;
			}
		}*/
		/// <summary>
		/// Number of lines in a text, separated by \n.
		/// </summary>
		public int LinesCount
		{
			get 
			{
				int lines = 1;
				int index = 0;
				while (-1 != (index = text.IndexOf("\\n",index)))
				{
					lines++;
					index++;
				}
				return lines;
			}
		}

		/// <summary>
		/// Plays sound when reminding for Desknote.
		/// Sound is played by extra thread to allow notification.
		/// </summary>
		internal void PlaySound()
		{
			if (dataHandler.PlaySound)
			{
				Thread t = new Thread(new ThreadStart(SoundThreadProc));
				t.Start();
				Thread.Sleep(5);
				//WinImports.PlaySound(dataHandler.SoundFile, 0, 0 );
			}
			else 
				WinImports.MessageBeep(WinImports.IconExclamation);
		}

		/// <summary>
		/// Thread callback plays the sound.
		/// </summary>
		private void SoundThreadProc()
		{
			WinImports.PlaySound(Properties.Settings.Default.SoundFile, 0, 0 );
		}

		/// <summary>
		/// Method performs either creation of new note and its insert into
		/// dataset or updates existing note. It is determined on desk note's ID. If ID is 0 (zero) then 
		/// it is a new desknote, if it has non zero value then it already exists in dataset and needs 
		/// to be updated.
        /// Does not save dataset to disk!
		/// </summary>
		internal void UpdateDataSet()
		{
			try 
			{
				if (this.id == 0)
				{
					CreateNewRecord();
				} 
				else
				{
					UpdateExisting();
				}
			} 
			catch (Exception e)
			{
				MessageBox.Show(MainResource.GetString("ERROR_RECORD_UPDATE") + e.Message, MainResource.GetString("APP_TITLE"),
					MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

        /// <summary>
        ///  Saves desknotes dataset to disk.
        /// </summary>
        internal void Save()
        {
            dataHandler.Save();
        }
		/// <summary>
		/// Creates new record for DeskNote in the Dataset. Auto generated ID is
		/// assigned to note ID property at the end of method.
		/// </summary>
		private void CreateNewRecord()
		{
            DeskNoteDB.DeskNoteRow rowNote = dataHandler._DeskNote.AddDeskNoteRow(this.alarm,
				this.backgroundColor.ToArgb(), this.textColor.ToArgb(), this.OnTop, this.Hidden, 
                this.text, this.opacity, this.outlookEntryID, this.lastModificationTime, this.syncTime, this.switchable, this.showFormatting);
			if (!this.HasAlarm)
				rowNote.SetalarmNull();
			
			//position saved
			dataHandler.position.AddpositionRow(rowNote, position.X,position.Y,position.Width,position.Height);
			
			dataHandler.AcceptChanges();
			this.id = rowNote.ID;
            dataHandler.Save();
		}


        /// <summary>
        /// Get DeskNote dataset row corresponding to this Note
        /// </summary>
        /// <returns>DeskNote.DeskNoteRow from dataset </returns>
        private DeskNoteDB.DeskNoteRow GetMyDataSetRow()
        {
			DeskNoteDB.DeskNoteDataTable tblDeskNotes = dataHandler._DeskNote;
			if (tblDeskNotes.Count == 0)
				//throw exception or something.
				return null;

			// Use the Select method to find all rows matching the filter.
			DeskNoteDB.DeskNoteRow[] foundRows = (DeskNoteDB.DeskNoteRow[]) tblDeskNotes.Select("ID = " + this.id.ToString());
            if (foundRows.Length >= 1)
            {
                return foundRows[0];
            }
            else
                return null;
        }

		/// <summary>
		/// Updates existing desknote in the dataset. 
		/// Note is found by its ID property.
		/// </summary>
		private void UpdateExisting(){
			
			DeskNoteDB.DeskNoteDataTable tblDeskNotes = dataHandler._DeskNote;
			if (tblDeskNotes.Count == 0)
				//throw exception or something.
				return;

			// Use the Select method to find all rows matching the filter.
			DeskNoteDB.DeskNoteRow[] foundRows = (DeskNoteDB.DeskNoteRow[]) tblDeskNotes.Select("ID = " + this.id.ToString());
			if (foundRows.Length >= 1)
			{
                foundRows[0].text = this.text;
                
				if (this.HasAlarm)
					foundRows[0].alarm = this.alarm;
				else
					foundRows[0].SetalarmNull();

				foundRows[0].textColor = this.textColor.ToArgb();
				foundRows[0].backColor = this.backgroundColor.ToArgb();
				foundRows[0].onTop = this.OnTop;
				foundRows[0].hidden = this.Hidden;
                foundRows[0].opacity = this.opacity;
                foundRows[0].OutlookEntryID = this.outlookEntryID;
                foundRows[0].LastModificationTime = this.lastModificationTime;
                foundRows[0].SyncTime = this.syncTime;
                foundRows[0].switchable = this.switchable;
                foundRows[0].ShowFormatting = this.showFormatting;

				//save position of desknote on the screen.
				DeskNoteDB.positionRow[] child = foundRows[0].GetpositionRows();
				if (child.Length != 0)
				{
					child[0].x = position.X;
					child[0].y = position.Y;
					child[0].width = position.Width;
					child[0].height = position.Height;
                    dataHandler.position.AcceptChanges();
				} 
				else 
				{
					dataHandler.position.AddpositionRow(foundRows[0], position.X,position.Y,
						position.Width, position.Height);
                    dataHandler.position.AcceptChanges();
				}
				
			}
			//tblDeskNotes.AcceptChanges();
		}

        

       
		/// <summary>
		/// Method reads all data for just read and created Note from dataset.
		/// Called from DeskNotes.ReadAllData()
		/// </summary>
		/// <param name="noteRow">DeskNote dataset row containing data for note to be read to fully initialized the note.</param>
		internal void ReadFromDataSet(DeskNoteDB.DeskNoteRow noteRow)
		{
			if (!noteRow.IsbackColorNull())
				this.backgroundColor = Color.FromArgb(noteRow.backColor);
			else 
				this.backgroundColor = Properties.Settings.Default.BackgroundColor;
				
			if (!noteRow.IstextColorNull())
				this.textColor = Color.FromArgb(noteRow.textColor);
			else
				this.textColor = Properties.Settings.Default.TextColor;
				
			if (!noteRow.IsonTopNull())
				this.onTop = noteRow.onTop;
			if (!noteRow.IshiddenNull())
				this.hidden = noteRow.hidden;
            if (!noteRow.IsswitchableNull())
                this.switchable = noteRow.switchable;
            if (!noteRow.IsopacityNull())
                this.opacity = noteRow.opacity;
            if (!noteRow.IsLastModificationTimeNull())
                this.lastModificationTime = noteRow.LastModificationTime;
            if (!noteRow.IsSyncTimeNull())
                this.syncTime = noteRow.SyncTime;
            if (!noteRow.IsShowFormattingNull())
                this.showFormatting = noteRow.ShowFormatting;

            this.text = noteRow.text;
            
            this.outlookEntryID = noteRow.OutlookEntryID;

			DeskNoteDB.positionRow[] position = noteRow.GetpositionRows();
			if (position.Length !=0)
			{
				this.position = new Rectangle(position[0].x, position[0].y,
					position[0].width, position[0].height);
			}
			DeskNoteDB.fontRow[] font = noteRow.GetfontRows();
			if (font.Length != 0)
			{
				FontStyle fontStyle = FontStyle.Regular;
				bool bold = font[0].bold;
				bool italic = font[0].italic;
				bool strikeout = font[0].strikeout;
				bool underline = font[0].underline;
				fontStyle |= bold ? FontStyle.Bold : 0;
				fontStyle |= italic ? FontStyle.Italic : 0;
				fontStyle |= strikeout ? FontStyle.Strikeout : 0;
				fontStyle |= underline ? FontStyle.Underline : 0;
				this.font = new Font(font[0].name, font[0].size, fontStyle);
			}
			if (!noteRow.IsalarmNull())
			{
				this.alarm = noteRow.alarm;
			}
		}

		/// <summary>
		/// Removes given note from dataset and performs save of XML data file.
		/// </summary>
		internal void RemoveRecord()
		{
            if (dataHandler.RemoveDeskNote(this.id))
            {
                // delete from dataset
                DeleteOutlookNote();
                //remove from DeskNotes collection
                dataHandler.Remove(this);
            }
   		
		}

        /// <summary>
        /// Gets the corresponding Outlook NoteItem if such exists.
        /// </summary>
        internal Outlook.NoteItem OutlookNoteItem 
        {
            get
            {
                if (null != this.outlookEntryID)
                {
                    Outlook.Application olApp = new Outlook.Application();
                    Outlook.NameSpace olSpace = olApp.GetNamespace("MAPI");
                    Outlook.MAPIFolder notesFolder = olSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderNotes);
                    try
                    {
                        Outlook.NoteItem olNote = (Outlook.NoteItem)olSpace.GetItemFromID(this.outlookEntryID, notesFolder.StoreID);
                        return olNote;
                    }
                    catch (System.Runtime.InteropServices.COMException ce)
                    {
                        this.outlookEntryID = null;
                        Logger.WriteLine("Note.OutlookNoteItem " + ce.Message + "\\n" + ce.StackTrace);
                        return null;
                    }
                }
                else
                    return null;
            }
        }


        /// <summary>
        /// Permanently deletes Outlook Note from Outlook Notes folder and also from DeletedItems folder
        /// </summary>
        private void DeleteOutlookNote()
        {
            Outlook.NoteItem olNote = this.OutlookNoteItem;
            if (null != olNote)
            {
                try
                {
                    if (Properties.Settings.Default.RemoveInOutlook)
                    {
                        // Delete from Notes folder
                        olNote.Delete();
                        // Delete from DeletedItems folder where it is
                        Outlook.Application olApp = new Outlook.Application();
                        Outlook.NameSpace olSpace = olApp.GetNamespace("MAPI");
                        Outlook.MAPIFolder notesFolder = olSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderDeletedItems);
                        Outlook.NoteItem olNoteDeleted = (Outlook.NoteItem)olSpace.GetItemFromID(this.outlookEntryID, notesFolder.StoreID);
                        olNoteDeleted.Delete();
                        olNote = null;
                        olNoteDeleted = null;
                    }
                }
                catch (Exception e)
                {
                    //do nothing if something failed then likely because item was not found.
                    Logger.WriteLine(e.Message + "\\n" + e.StackTrace);
                }
            }
        }

        internal SynchronizationConflictDlg.Result SynchronizeOutlook(Form form, 
            ref SynchronizationConflictDlg.Result nextResult)
        {
            
            Outlook.Application olApp = new Outlook.Application();
            //SaveText();
            if (null == outlookEntryID)
            {
                Outlook.NoteItem n = (Outlook.NoteItem)olApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olNoteItem);
                n.Body = MyForm.TextEx;
                n.Categories = "DeskNotes";
                n.Save();
                OutlookEntryID = n.EntryID;
                SyncTime = n.LastModificationTime;
                return SynchronizationConflictDlg.Result.KeepDeskNote;
            }
            else // DeskNote was already saved in Outlook perform synchronization.
            {

                Outlook.NoteItem olNote = OutlookNoteItem;
                if (null == olNote)
                {
                    return SynchronizationConflictDlg.Result.OutlookMissing;
                }
                DateTime olTime = olNote.LastModificationTime;
                int timeS2O = SyncTime.CompareTo(olTime);
                int timeD2S = LastModificationTime.CompareTo(SyncTime);
                if ((timeD2S <= 0) && (timeS2O < 0))
                {
                    //DeskNote is older or same as Sync and Outlook is newer than Sync
                    //Synchronize to DeskNote and set Modification time to the one from Outlook
                    myForm.TextEx = olNote.Body;
                    this.Text = MyForm.TextEx;
                    SyncTime = olNote.LastModificationTime;
                    LastModificationTime = olNote.LastModificationTime;
                    return SynchronizationConflictDlg.Result.KeepOutlook;
                }
                else if ((timeD2S > 0) && (timeS2O >= 0))
                {
                    // DeskNote is newer than Sync and Outlook is older or same as Sync
                    // Synchronize to Outlook
                    olNote.Body = MyForm.TextEx;
                    olNote.Save();
                    SyncTime = olNote.LastModificationTime;
                    return SynchronizationConflictDlg.Result.KeepDeskNote;
                }
                else if ((timeD2S > 0) && (timeS2O < 0))
                {
                    // Desknote is newer than Sync time and Outlook is newer than Sync time
                    // Ask USER for resolution
                    SynchronizationConflictDlg.Result result;
                    // If synchronization of All notes just started or only one note is being synced
                    // then proceed to dialog show
                    if ((nextResult != SynchronizationConflictDlg.Result.SyncAll) &&
                        (nextResult != SynchronizationConflictDlg.Result.SyncOne))
                    {
                        result = nextResult;
                    }
                    else
                    {
                        SynchronizationConflictDlg syncDlg = new SynchronizationConflictDlg(this, olTime);
                        if (nextResult == SynchronizationConflictDlg.Result.SyncAll)
                            syncDlg.chkSameConflicts.Visible = true;
                        result = syncDlg.ShowDialog(form);
                        if (syncDlg.chkSameConflicts.Checked)
                        {
                            nextResult = result;
                        }
                    }
                    switch (result)
                    {
                        case SynchronizationConflictDlg.Result.KeepDeskNote:
                            // Synchronize DeskNote to Outlook
                            olNote.Body = myForm.TextEx;
                            olNote.Save();
                            SyncTime = olNote.LastModificationTime;
                            break;
                        case SynchronizationConflictDlg.Result.KeepOutlook:
                            // Synchronize Outlook to Desknote
                            string t = olNote.Body;
                            myForm.ResetAppearance();
                            myForm.TextEx = t;
                            //textChanged = false;
                            SyncTime = olNote.LastModificationTime;
                            LastModificationTime = olNote.LastModificationTime;
                            Text = myForm.Rtf;
                            this.font = Properties.Settings.Default.Font;
                            this.UpdateDataSet();
                            break;
                        case SynchronizationConflictDlg.Result.Merge:
                            // Add Outlook text under Desknote
                            System.Text.StringBuilder text = new System.Text.StringBuilder(Text);
                            text.Append("\r\n");
                            text.AppendFormat(Resources.AppResource.OutlookMergedText, DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString());
                            text.Append("\r\n");
                            text.Append(olNote.Body);
                            olNote.Body = text.ToString();
                            olNote.Save();
                            myForm.TextEx = text.ToString();
                            //textChanged = false;
                            SyncTime = olNote.LastModificationTime;
                            LastModificationTime = olNote.LastModificationTime;
                            Text = myForm.TextEx;
                            break;
                        default:
                            break;
                    }
                    return result;
                }
                return SynchronizationConflictDlg.Result.Cancel;
            }
            
        }

		#region IPrintableNote Members

		public string HeaderText
		{
			get
			{
				return string.Format(MainResource.GetString("REMINDER"), this.AlarmText);
			}
		}

		public bool HasHeader
		{
			get
			{
				return this.HasAlarm;
			}
		}

		public StringAlignment HeaderAlign
		{
			get
			{
				return StringAlignment.Center;
			}
		}

		public Font GetOwnFont
		{
			get
			{
				return ExtraFont;
			}
		}

		public string BodyText
		{
			get {
				//return RtfConverter.Text(text);
                return RtfConverter.Rtf(text);
			}
		}

		#endregion
	}
}
